package com.wac.common.util;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author wuancheng
 * @date 2023/11/6 17:01
 * @description
 */
public class HttpClientUtils {
    private static final Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
    private static volatile CloseableHttpClient httpClient = null;
    private static final Object SYNC_LOCK = new Object();
    private static final int DEFAULT_MAX_TOTAL = 100;
    private static final int DEFAULT_MAX_PER_ROUTE = 20;
    private static final int SOCKET_TIMEOUT = 20000;
    private static final int CONNECT_TIMEOUT = 5000;
    private static final int CONNECTION_REQUEST_TIMEOUT = 1000;

    public HttpClientUtils() {
    }

    /**
     * 双重检测创建httpClient
     *
     * @return
     */
    private static CloseableHttpClient getHttpClient() {
        if (httpClient == null) {
            synchronized(SYNC_LOCK) {
                if (httpClient == null) {
                    httpClient = createHttpClient(100, 20);
                }
            }
        }

        return httpClient;
    }

    private static CloseableHttpClient createHttpClient(int maxTotal, int maxPerRoute) {
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(5000).setConnectionRequestTimeout(1000).build();
        return HttpClients.custom().setMaxConnTotal(maxTotal).setMaxConnPerRoute(maxPerRoute).setDefaultRequestConfig(requestConfig).build();
    }

    public static String doPostJson(String url, Map<String, Object> params) throws Exception {
        return doPostJson(url, params, null, null);
    }

    public static String doPostJson(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        return doPostJson(url, JSONObject.toJSONString(params), headers);
    }

    public static String doPostJson(String url, String json) throws Exception {
        return doPostJson(url, json, null, null);
    }

    public static <T> T doPostJsonReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doPostJson(url, params, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPostJsonReturnObject(String url, Map<String, Object> params, Class<T> clazz) throws Exception {
        String resultJson = doPostJson(url, params);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, Map<String, Object> params) throws Exception {
        String resultJson = doPostJson(url, params);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        String resultJson = doPostJson(url, params, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doPostJsonReturnObject(String url, String json, Class<T> clazz) throws Exception {
        String resultJson = doPostJson(url, json);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPostJsonReturnObject(String url, String json, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doPostJson(url, json, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, String json, Map<String, String> headers) throws Exception {
        String resultJson = doPostJson(url, json, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, String json) throws Exception {
        String resultJson = doPostJson(url, json);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doPostJson(String url, String json, Map<String, String> headers) throws Exception {
        return doPostJson(url, json, headers, null);
    }

    public static String doPostXml(String url, String xml) throws Exception {
        return doPostXml(url, xml, null, null);
    }

    public static String doPostXml(String url, String xml, Map<String, String> headers) throws Exception {
        return doPostXml(url, xml, headers, null);
    }

    public static String doPostJson(String url, Map<String, Object> params, RequestConfig reqConfig) throws Exception {
        return doPostJson(url, params, null, reqConfig);
    }

    public static String doPostJson(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doPostJson(url, JSONObject.toJSONString(params), headers, reqConfig);
    }

    public static String doPostJson(String url, String json, RequestConfig reqConfig) throws Exception {
        return doPostJson(url, json, null, reqConfig);
    }

    public static <T> T doPostJsonReturnObject(String url, Map<String, Object> params, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, params, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPostJsonReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, Map<String, Object> params, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, params, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doPostJsonReturnObject(String url, String json, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, json, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPostJsonReturnMap(String url, String json, RequestConfig reqConfig) throws Exception {
        String resultJson = doPostJson(url, json, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doPostJson(String url, String json, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doPostOrPutRequest(url, json, "POST", headers, reqConfig, ContentType.APPLICATION_JSON);
    }

    public static String doPostXml(String url, String xml, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doPostOrPutRequest(url, xml, "POST", headers, reqConfig, ContentType.APPLICATION_XML);
    }

    public static String doPutJson(String url, Map<String, Object> params) throws Exception {
        return doPutJson(url, params, null, null);
    }

    public static String doPutJson(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        return doPutJson(url, JSONObject.toJSONString(params), headers);
    }

    public static String doPutJson(String url, String json) throws Exception {
        return doPutJson(url, json, null, null);
    }

    public static <T> T doPutJsonReturnObject(String url, Map<String, Object> params, Class<T> clazz) throws Exception {
        String resultJson = doPutJson(url, params);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPutJsonReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doPutJson(url, params, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, Map<String, Object> params) throws Exception {
        String resultJson = doPutJson(url, params);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        String resultJson = doPutJson(url, params, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doPutJsonReturnObject(String url, String json, Class<T> clazz) throws Exception {
        String resultJson = doPutJson(url, json);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, String json, Map<String, String> headers) throws Exception {
        String resultJson = doPutJson(url, json, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doPutJson(String url, String json, Map<String, String> headers) throws Exception {
        return doPutJson(url, json, headers, null);
    }

    public static String doPutJson(String url, Map<String, Object> params, RequestConfig reqConfig) throws Exception {
        return doPutJson(url, params, null, reqConfig);
    }

    public static String doPutJson(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doPutJson(url, JSONObject.toJSONString(params), headers, reqConfig);
    }

    public static String doPutJson(String url, String json, RequestConfig reqConfig) throws Exception {
        return doPutJson(url, json, null, reqConfig);
    }

    public static <T> T doPutJsonReturnObject(String url, Map<String, Object> params, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, params, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPutJsonReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, Map<String, Object> params, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, params, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, String json, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, json, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doPutJsonReturnObject(String url, String json, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, json, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static <T> T doPutJsonReturnObject(String url, String json, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, json, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doPutJsonReturnMap(String url, String json, RequestConfig reqConfig) throws Exception {
        String resultJson = doPutJson(url, json, null, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doPutJson(String url, String json, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doPostOrPutRequest(url, json, "PUT", headers, reqConfig, ContentType.APPLICATION_JSON);
    }

    public static <T> T doDeleteReturnObject(String url, Class<T> clazz) throws Exception {
        String resultJson = doDelete(url);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url) throws Exception {
        String resultJson = doDelete(url);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doDeleteReturnObject(String url, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doDelete(url, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url, Map<String, String> headers) throws Exception {
        String resultJson = doDelete(url, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doDeleteReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doDelete(url, params, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        String resultJson = doDelete(url, params, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doDelete(String url) throws Exception {
        return doDelete(url, null, null, null);
    }

    public static String doDelete(String url, Map<String, String> headers) throws Exception {
        return doDelete(url, null, headers);
    }

    public static String doDelete(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        return doDelete(url, params, headers, null);
    }

    public static <T> T doDeleteReturnObject(String url, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doDeleteReturnObject(String url, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doDeleteReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doDeleteReturnMap(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doDelete(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doDelete(String url, RequestConfig reqConfig) throws Exception {
        return doDelete(url, null, (RequestConfig)reqConfig);
    }

    public static String doDelete(String url, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doDelete(url, null, headers, reqConfig);
    }

    public static String doDelete(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doGetOrDeleteRequest(url, params, headers, "DELETE", reqConfig);
    }

    public static <T> T doGetReturnObject(String url, Class<T> clazz) throws Exception {
        String resultJson = doGet(url);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doGetReturnMap(String url) throws Exception {
        String resultJson = doGet(url);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doGetReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doGet(url, params, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doGetReturnMap(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        String resultJson = doGet(url, params, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doGetReturnObject(String url, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultJson = doGet(url, headers);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doGetReturnMap(String url, Map<String, String> headers) throws Exception {
        String resultJson = doGet(url, headers);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static String doGet(String url, Map<String, String> headers) throws Exception {
        return doGet(url, null, headers);
    }

    public static String doGet(String url) throws Exception {
        return doGet(url, null);
    }

    public static String doGet(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
        return doGet(url, params, headers, null);
    }

    public static <T> T doGetReturnObject(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doGet(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static Map<String, Object> doGetReturnMap(String url, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doGet(url, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static Map<String, Object> doGetReturnMap(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        String resultJson = doGet(url, params, headers, reqConfig);
        return JSONObject.parseObject(resultJson, Map.class);
    }

    public static <T> T doGetReturnObject(String url, Map<String, String> headers, Class<T> clazz, RequestConfig reqConfig) throws Exception {
        String resultJson = doGet(url, headers, reqConfig);
        return JSONObject.parseObject(resultJson, clazz);
    }

    public static String doGet(String url, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doGet(url, null, headers, reqConfig);
    }

    public static String doGet(String url, Map<String, Object> params, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        return doGetOrDeleteRequest(url, params, headers, "GET", reqConfig);
    }

    private static String doGetOrDeleteRequest(String url, Map<String, Object> params, Map<String, String> headers, String httpMethod, RequestConfig reqConfig) throws Exception {
        CloseableHttpResponse response = null;
        HttpRequestBase httpRequest = null;
        String result = null;

        try {
            httpRequest = buildHttpRequestBase(url, httpMethod, params);
            if (null != reqConfig) {
                httpRequest.setConfig(reqConfig);
            }

            setHeader(headers, httpRequest);
            reqHeaderPrintLog(httpRequest);
            response = getHttpClient().execute(httpRequest);
            respHeaderPrintLog(response);
            result = getResponseResult(response);
        } finally {
            if (response != null) {
                response.close();
            }

        }

        return result;
    }

    private static String doPostOrPutRequest(String url, String reqData, String httpMethod, Map<String, String> headers, RequestConfig reqConfig, ContentType contentType) throws Exception {
        CloseableHttpResponse response = null;
        HttpEntityEnclosingRequestBase httpRequest = null;
        String result = null;

        try {
            if (log.isDebugEnabled()) {
                log.debug("send request url:{},requestBody:{}", url, reqData);
            }

            httpRequest = buildHttpRequest(url, httpMethod);
            if (null != reqConfig) {
                httpRequest.setConfig(reqConfig);
            }

            setHeader(headers, httpRequest);
            httpRequest.setHeader("Content-Type", contentType.toString());
            if (StringUtils.isNotBlank(reqData)) {
                httpRequest.setEntity(new StringEntity(reqData, contentType));
            }

            reqHeaderPrintLog(httpRequest);
            response = getHttpClient().execute(httpRequest);
            respHeaderPrintLog(response);
            result = getResponseResult(response);
        } finally {
            if (response != null) {
                response.close();
            }

        }

        return result;
    }

    private static String getResponseResult(CloseableHttpResponse response) throws IOException {
        String result = null;
        int statusCode = response.getStatusLine().getStatusCode();
        HttpEntity entity = response.getEntity();
        if (null != entity) {
            result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
            if (log.isDebugEnabled()) {
                log.debug("response result: {}", result);
            }
        }

        EntityUtils.consume(entity);
        if (statusCode != 200) {
            throw new IllegalStateException("Execute request failed [" + result + "], statusCode [" + statusCode + "]");
        } else {
            return result;
        }
    }

    private static void reqHeaderPrintLog(HttpRequestBase httpRequest) {
        if (log.isDebugEnabled()) {
            Header[] headersArray = httpRequest.getAllHeaders();
            Header[] var2 = headersArray;
            int var3 = headersArray.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                Header header = var2[var4];
                log.debug("request header: {}={}", header.getName(), header.getValue());
            }
        }

    }

    private static void respHeaderPrintLog(CloseableHttpResponse response) {
        if (log.isDebugEnabled()) {
            Header[] var1 = response.getAllHeaders();
            int var2 = var1.length;

            for(int var3 = 0; var3 < var2; ++var3) {
                Header header = var1[var3];
                log.debug("response header: {}={}", header.getName(), header.getValue());
            }
        }

    }

    private static HttpEntityEnclosingRequestBase buildHttpRequest(String url, String httpMethod) {
        HttpEntityEnclosingRequestBase httpRequest = null;
        if ("POST".equalsIgnoreCase(httpMethod)) {
            httpRequest = new HttpPost(url);
        } else if ("PUT".equalsIgnoreCase(httpMethod)) {
            httpRequest = new HttpPut(url);
        }

        return (HttpEntityEnclosingRequestBase)httpRequest;
    }

    private static HttpRequestBase buildHttpRequestBase(String url, String httpMethod, Map<String, Object> params) throws URISyntaxException {
        if (params != null && !params.isEmpty()) {
            URIBuilder uriBuilder = new URIBuilder(url);
            Iterator var4 = params.entrySet().iterator();

            while(var4.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var4.next();
                if (!ObjectUtils.isEmpty(entry.getValue())) {
                    uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
                }
            }

            url = uriBuilder.toString();
        }

        HttpRequestBase httpRequest = null;
        if ("GET".equalsIgnoreCase(httpMethod)) {
            httpRequest = new HttpGet(url);
        } else if ("DELETE".equalsIgnoreCase(httpMethod)) {
            httpRequest = new HttpDelete(url);
        }

        return (HttpRequestBase)httpRequest;
    }

    private static void setHeader(Map<String, String> headers, HttpRequestBase httpRequestBase) {
        if (headers != null && !headers.isEmpty()) {
            Set<Map.Entry<String, String>> entrySet = headers.entrySet();
            Iterator var3 = entrySet.iterator();

            while(var3.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var3.next();
                httpRequestBase.setHeader(entry.getKey(), entry.getValue());
            }
        }

    }

    public static String downloadImgToBase64(String mediaUrl) throws Exception {
        String base64 = null;
        CloseableHttpResponse resp = null;
        InputStream is = null;

        try {
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
            HttpGet httpGet = new HttpGet(mediaUrl);
            httpGet.setConfig(requestConfig);
            resp = getHttpClient().execute(httpGet);
            is = resp.getEntity().getContent();
            base64 = Base64.encode(is);
        } finally {
            if (is != null) {
                is.close();
            }

            if (resp != null) {
                resp.close();
            }

        }

        return base64;
    }

    public static String doPostForm(String url, Map<String, Object> formParams) throws Exception {
        return doPostForm(url, formParams, null, null);
    }

    public static String doPostForm(String url, Map<String, Object> formParams, Map<String, String> headers) throws Exception {
        return doPostForm(url, formParams, headers, null);
    }

    public static Map<String, Object> doPostFormReturnMap(String url, Map<String, Object> formParams, Map<String, String> headers) throws Exception {
        String resultStr = doPostForm(url, formParams, headers);
        return JSONObject.parseObject(resultStr, Map.class);
    }

    public static <T> T doPostFormReturnObject(String url, Map<String, Object> formParams, Map<String, String> headers, Class<T> clazz) throws Exception {
        String resultStr = doPostForm(url, formParams, headers);
        return JSONObject.parseObject(resultStr, clazz);
    }

    public static Map<String, Object> doPostFormReturnMap(String url, Map<String, Object> formParams, Map<String, String> headers, RequestConfig requestConfig) throws Exception {
        String resultStr = doPostForm(url, formParams, headers, requestConfig);
        return JSONObject.parseObject(resultStr, Map.class);
    }

    public static <T> T doPostFormReturnObject(String url, Map<String, Object> formParams, Map<String, String> headers, RequestConfig requestConfig, Class<T> clazz) throws Exception {
        String resultStr = doPostForm(url, formParams, headers, requestConfig);
        return JSONObject.parseObject(resultStr, clazz);
    }

    public static Map<String, Object> doPostFormReturnMap(String url, Map<String, Object> formParams) throws Exception {
        String resultStr = doPostForm(url, formParams);
        return JSONObject.parseObject(resultStr, Map.class);
    }

    public static <T> T doPostFormReturnObject(String url, Map<String, Object> formParams, Class<T> clazz) throws Exception {
        String resultStr = doPostForm(url, formParams);
        return JSONObject.parseObject(resultStr, clazz);
    }

    public static String doPostForm(String url, Map<String, Object> formParams, Map<String, String> headers, RequestConfig reqConfig) throws Exception {
        CloseableHttpResponse response = null;
        String result = null;

        try {
            if (log.isDebugEnabled()) {
                log.debug("send request url:{},formParams:{}", url, formParams);
            }

            HttpPost httpPost = new HttpPost(url);
            if (null != reqConfig) {
                httpPost.setConfig(reqConfig);
            }

            setHeader(headers, httpPost);
            httpPost.setHeader("Content-Type", ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
            List<NameValuePair> nameValuePairs = new ArrayList(formParams.size());
            Iterator var8 = formParams.entrySet().iterator();

            while(var8.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var8.next();
                if (!ObjectUtils.isEmpty(entry.getValue())) {
                    nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                }
            }

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            reqHeaderPrintLog(httpPost);
            response = getHttpClient().execute(httpPost);
            respHeaderPrintLog(response);
            result = getResponseResult(response);
        } finally {
            if (response != null) {
                response.close();
            }

        }

        return result;
    }

    public static void main(String[] args) throws Exception {
        doGet("http://www.baidu.com");
        TimeUnit.SECONDS.sleep(2147483647L);
    }
}


